package JeuDeLaVie;

import java.io.Serializable;

public class Case extends Thread implements Serializable
{
    private int clef;               // clef distinctive de la case
    private boolean etatCourant;    // état actuel de la case
    private boolean etatSuivant;    // état de la case au pas de temps suivant
    private transient Case[] tabVoisins;      // tableau répertoriant les voisins de la case
    private transient Regles reglesAct;       // règles en vigeur sur cette case
    
//    public int tempVois;

    //===================
    //      Fonctions
    //===================

    /**
     * Initialisation :
     * On initialise les états
     * On réserve la mémoire pour le tableau des voisisn
     */
    public Case()
    {
        initCase();
        tabVoisins = new Case[8];
        reglesAct = new ReglesBases();
    }

    
    @Override
     public void run()
    {
	calculEtatSuivant();
    }
    
    /**
     * Initialisation des états : tout le monde à false !
     */
    public void initCase(){
        this.etatCourant = false;
        this.etatSuivant = false;
    }
    
    

    /**
     * Si l'état courant de la case est true, le passe à false et inversement
     */
    public void inverseEtatCourant()
    {
        this.etatCourant = !this.etatCourant;
    }
    
    public void setEtatCourant(boolean nouvEtat){
        etatCourant = nouvEtat;
    }

    public void majEtatCourant()
    {
        this.etatCourant = this.etatSuivant;
    }
    
    //===========================================
    // quelques set, car il est des informations
    // que seul l'Environnement détient
    //===========================================
    
    public void setClef(int c){
        clef = c;
    }

    /* tire aléatoirement un état courant pour la case donnée */
    public void setAleaEtat()
    {
        int a = (int) (Math.random() * 2);

        if (a == 1)
        {
            this.etatCourant = true;
        }
        else{
            this.etatCourant = false;
        }

    }
    
    public void setCaseVoisin(Case vois, int num){
        tabVoisins[num] = vois;
    }
    
    public void setRegles(Regles nouvRegles){
        reglesAct = nouvRegles;
    }
    
    //===================================
    // Des gets (ça peut toujours servir)
    //===================================
    /**
     * Fonction permettant de connaître l'état de la case. Si elle est vivante,
     * retournera true ; sinon, retournera false.
     * @return boolean
     */
    public boolean getEtatCourant(){
        return etatCourant;
    }
    
    /**
     * Fonction permettant de connaître la clef correspondant à la case.
     * @return int
     */
    public int getClef(){
        return clef;
    }
    
    public Case[] getVoisinsCase(){
        return tabVoisins;
    }
    

    /* !!!!! Fonction non définitive !!!!
     *    Pour l'instant, se base sur le nombre de voisines vivantes
     *    qu'on lui aurait hypothétiquement passé ; mais ça peut se changer
     */
    public void calculEtatSuivant()
    {
//        etatSuivant = regle(this);
        etatSuivant = reglesAct.regles(this);
        /*
        int nbVoisinesViv = 0;
        
        for(int i=0; i<tabVoisins.length; i++){
            if(tabVoisins[i].etatCourant){
                nbVoisinesViv++;
            }
        }
        
        this.tempVois = nbVoisinesViv;
        
        if (nbVoisinesViv == 3)
        {
            this.etatSuivant = true;
        } 
        
        else // si la cellule actuelle est vivante
        if ((this.etatCourant)&&(nbVoisinesViv == 2))
        {
                this.etatSuivant = true;
        }

        else
        {
            this.etatSuivant = false;
        }
        * */
    }
    
    //=============================
    // Gestion de nouvelles règles
    //=============================
    public boolean regle(Case caseAct){
        int nbVoisinesViv = 0;
        
        for(int i=0; i<tabVoisins.length; i++){
            if(caseAct.getVoisinsCase()[i].etatCourant){
                nbVoisinesViv++;
            }
        }
        
        if (nbVoisinesViv == 3)
        {
            return true;
        } 
        
        else // si la cellule actuelle est vivante
        if ((caseAct.etatCourant)&&(nbVoisinesViv == 2))
        {
                return true;
        }

        else
        {
            return false;
        }
    }
    
    
}
